/* eslint-disable prefer-const */
import { isArray } from "@/utils/is";
import { isNotEmptyObject } from "@/utils/common";
import { message, TableColumnType } from "antd";
// import { CustomColumn } from "../ProTable/typing";
import { aoaToSheetXlsx } from "./Excel";
import { HeaderData } from "./typing";

export type ExportParamType = {
  columns: TableColumnType[];
  data: [];
  fileName?: string;
  exportColumnFormat?: ExportColumnFormatType;
  merges?: any[];
};

export type ExportColumnFormatType = (key: any, value: any) => void;

/**
 * @Description: 导出 Excel
 * @Author: knight
 * @Date: 2022-06-10 15:54:14
 */
export function excelExport(param: ExportParamType) {
  const { columns, data, fileName, exportColumnFormat, merges } = param;
  if (!data || data.length === 0) {
    message.open({
      type: "warning",
      content: "没有数据可以导出！",
    });
    return;
  }

  const selectedColumns = getSelectedColumns(columns);
  console.log("selectedColumns", selectedColumns);

  aoaToSheetXlsx({
    data: getSheetData(data, selectedColumns, exportColumnFormat),
    // header: getSheetHeader(selectedColumns),
    headerData: getSheetHeaderData(selectedColumns),
    filename: fileName ?? "导出文件",
    merges: merges,
  });
}

/**
 * @Description: 获取表单数据
 * @Author: knight
 * @Date: 2021/5/7 16:30
 */
function getSheetData(
  data: [],
  columns: TableColumnType[],
  exportColumnFormat?: ExportColumnFormatType
) {
  const dataTable: any = [];
  data.forEach((item: any) => {
    let obj = transformData(flattenArray(columns), item, exportColumnFormat);
    obj = Object.keys(obj).map((key) => obj[key]);
    dataTable.push(obj);
  });
  return dataTable;
}

/**
 * @Description: 转换表单数据
 * @Author: knight
 * @Date: 2021/5/7 16:30
 */
function transformData(
  columns: TableColumnType[],
  value: any,
  exportColumnFormat?: ExportColumnFormatType
) {
  let obj = {};
  columns.forEach((item: TableColumnType) => {
    const data = {};
    const key: any = item.key || item.dataIndex;

    if (key && typeof key === "string") {
      switch (key) {
        case "age": {
          data[key] = isNotEmptyObject(value?.age) ? value?.age : value?.age;
          break;
        }

        default: {
          if (item.dataIndex && typeof item.dataIndex === "string") {
            // if (item?.valueEnum) {
            //   data[key] = item.valueEnum[value[item.dataIndex]]?.text;
            // } else {
            data[key] = value[item.dataIndex];
            // }
          }
        }
      }

      // 自定义格式化方法
      if (exportColumnFormat) {
        const ret = exportColumnFormat(key, value);
        if (isNotEmptyObject(ret)) {
          data[key] = ret;
        }
      }
    }

    obj = { ...obj, ...data };
  });
  return obj;
}

/**
 * @Description: 获取sheetHeader
 * @Author: knight
 * @Date: 2021/5/7 16:29
 */
function getSheetHeader(columns: TableColumnType[]) {
  const list: any[] = [];
  columns.forEach((item: TableColumnType) => {
    list.push(item.title);
  });
  return list;
}

/**
 * @Description: 获取有效的列表项
 * @Author: knight
 * @Date: 2022-06-10 15:41:27
 */
function getSelectedColumns(columns: TableColumnType[]): TableColumnType[] {
  return columns.filter((item: any) => !item.hideInTable);
}

/**
 * @Description: 获取sheetHeaderData（支持多行，支持合并标题）
 * @Author: knight
 * @Date: 2024-05-20 14:47:33
 */
function getSheetHeaderData(columns: TableColumnType[]): HeaderData {
  const result: HeaderData = {
    list: [],
    merges: [],
    maxDepth: 1,
  };

  const maxDepth = calculateMaxDepth(columns);
  console.log(`The maximum depth of the tree is: ${maxDepth}`);
  for (let i = 0; i < maxDepth; i++) {
    result.list.push([]);
  }
  result.maxDepth = maxDepth;

  // const totalDescendantsCount = columns.reduce((sum, item) => sum + countNodes(item), 0);
  // console.log(`The total number of descendants is: ${totalDescendantsCount}`);

  columns.forEach((item: any) => {
    getListData(result, item);
  });

  return result;
}

/**
 * @Description: 计算行数（最大深度）
 * @Author: knight
 * @Date: 2024-05-20 14:09:25
 */
function calculateMaxDepth(data) {
  // 递归辅助函数
  function traverse(node, depth = 1) {
    if (!node.children || node.children.length === 0) {
      // 如果没有子节点，返回当前深度
      return depth;
    }

    // 遍历每个子节点，并返回最大深度
    let maxChildDepth = 0;
    for (let child of node.children) {
      const childDepth = traverse(child, depth + 1);
      if (childDepth > maxChildDepth) {
        maxChildDepth = childDepth;
      }
    }
    return maxChildDepth;
  }

  // 遍历数据中的每个一级标题（节点）并找到最大深度
  let maxDepth = 0;
  for (let item of data) {
    const itemDepth = traverse(item);
    if (itemDepth > maxDepth) {
      maxDepth = itemDepth;
    }
  }

  return maxDepth;
}

/**
 * @Description: 计算列数
 * @Author: knight
 * @Date: 2024-05-20 14:09:46
 */
function countNodes(node) {
  let count = 0; // 初始计数为0

  // 如果节点有children并且children不为空数组
  if (
    node.children &&
    Array.isArray(node.children) &&
    node.children.length > 0
  ) {
    // 递归计算子节点的数量
    for (let child of node.children) {
      count += countNodes(child); // 累加子节点的数量
    }
  } else {
    // 如果没有children或者children为空数组，节点计为一个
    count += 1;
  }

  return count;
}

/**
 * @Description: 计算并填充标题内容
 * @Author: knight
 * @Date: 2024-05-20 15:21:11
 */
function getListData(result, item, depth = 1) {
  let count = 0; // 初始计数为0

  // 如果节点有children并且children不为空数组
  if (
    item.children &&
    Array.isArray(item.children) &&
    item.children.length > 0
  ) {
    // 递归计算子节点的数量
    for (let child of item.children) {
      count += getListData(result, child, depth + 1); // 累加子节点的数量
    }
  } else {
    // 如果没有children或者children为空数组，节点计为一个
    count += 1;
  }

  if (count === 1) {
    for (let i = depth; i <= result.maxDepth; i++) {
      result.list[i - 1].push(item.title);
    }
    result.merges.push({
      s: { r: depth, c: result.list[depth - 1].length - 1 }, // s ("start"): c = 1 r = 2 -> "B3"
      e: { r: result.maxDepth, c: result.list[depth - 1].length - 1 }, // e ("end"):   c = 4 r = 3 -> "E4"
    });
  } else {
    for (let i = 0; i < count; i++) {
      result.list[depth - 1].push(item.title);
    }
    result.merges.push({
      s: { r: depth, c: result.list[depth - 1].length - count }, // s ("start"): c = 1 r = 2 -> "B3"
      e: { r: depth, c: result.list[depth - 1].length - 1 }, // e ("end"):   c = 4 r = 3 -> "E4"
    });
  }

  return count;
}

/**
 * @Description: 将多层嵌套的数组扁平化
 * @Author: knight
 * @Date: 2024-05-20 16:16:30
 */
export function flattenArray(arr) {
  // eslint-disable-next-line prefer-const
  let result: any[] = [];

  // 递归函数
  function flatten(items) {
    for (let i = 0; i < items.length; i++) {
      // 如果有 children，则递归处理 children，但不将父节点添加到结果中
      if (items[i].children && Array.isArray(items[i].children)) {
        flatten(items[i].children);
      } else {
        // 如果没有 children，则将父节点添加到结果中
        result.push(items[i]);
      }
    }
  }

  // 开始递归
  flatten(arr);

  return result;
}
